# -*- coding: utf-8 -*- # 建议保留这一行，确保文件编码

# 基础数据分析工具
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor

from scipy.stats import pearsonr, spearmanr
from sklearn.preprocessing import MinMaxScaler

# ... 后面的导入和函数定义保持不变
from tqdm import tqdm
import seaborn as sns
from datetime import datetime


import matplotlib

matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib
# ======================================================
# 确保中文字体名称正确，可以尝试不同的字体名称列表
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial']
# 解决负号'-'显示为方块的问题
matplotlib.rcParams['axes.unicode_minus'] = False
# ======================================================



def data_overview(data):
    """数据概览报告"""
    print("\n[数据概览] 正在分析数据集...")
    print(f"数据集维度: {data.shape}")
    print("前5行数据预览:")
    print(data.head(3))
    print("\n变量类型统计:")
    print(data.dtypes.value_counts())
    print("\n缺失值统计:")
    print(data.isnull().sum())


def concordance_correlation_coefficient(y_true, y_pred):
    """一致性相关系数计算"""
    mean_true = np.mean(y_true)
    mean_pred = np.mean(y_pred)
    var_true = np.var(y_true)
    var_pred = np.var(y_pred)
    covar = np.cov(y_true, y_pred)[0, 1]
    ccc = (2 * covar) / (var_true + var_pred + (mean_true - mean_pred) ** 2)
    return ccc


def enhanced_evaluation(y_true, y_pred):
    """增强评估指标（扩展指标）"""
    metrics = {
        'R²': pearsonr(y_true, y_pred)[0] ** 2,
        'CCC': concordance_correlation_coefficient(y_true, y_pred),
        'RMSE': np.sqrt(np.mean((y_true - y_pred) ** 2)),
        'MAE': np.mean(np.abs(y_true - y_pred)),
        # 'Spearman': spearmanr(y_true, y_pred)[0]  # 指标
    }
    return metrics


def plot_importance(feature_names, importances):
    """特征重要性可视化"""
    plt.figure(figsize=(12, 8))
    sns.barplot(x=importances, y=feature_names, palette="viridis", orient='h')
    plt.title('特征重要性排序', fontsize=14)
    plt.xlabel('重要性得分', fontsize=12)
    plt.ylabel('特征名称', fontsize=12)
    plt.xticks(rotation=45)
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.savefig(f'feature_importance_{datetime.now().strftime("%Y%m%d%H%M")}.png')  # 带时间戳保存
    plt.show()


def do_once():
    """主流程函数（时间记录）"""
    start_time = time.time()

    # 数据加载
    data = pd.read_excel(r'C:\Users\32407\Desktop\soil-terrain attributes.xlsx')
    data_overview(data)  # 数据概览

    X = data.drop('SD', axis=1).values
    y = data['SD'].values

    # 数据归一化
    scaler = MinMaxScaler()
    X = scaler.fit_transform(X)

    # 数据划分
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=None)

    # 模型配置（增加参数注释）
    rf = RandomForestRegressor(
        n_estimators=500,  # 基学习器数量
        max_features='sqrt',  # 特征选择策略
        min_samples_leaf=2,  # 防止过拟合
        random_state=42,
        n_jobs=-1  # 并行加速
    )

    # 训练模型（增加时间记录）
    rf.fit(X_train, y_train)
    train_time = time.time() - start_time
    print(f"模型训练完成，耗时: {train_time:.2f}秒")

    # 特征重要性
    feature_importances = rf.feature_importances_

    # 预测与评估
    pre_test = rf.predict(X_test)
    metrics = enhanced_evaluation(y_test, pre_test)  # 改用增强评估

    return np.array([metrics['R²'], metrics['CCC'], metrics['RMSE'], metrics['MAE']]), feature_importances


# 实验运行模块（增加进度条）
if __name__ == "__main__":
    import time

    start_experiment = time.time()

    # 实验配置
    N_REPEATS = 10  # 实际运行时设为1000
    all_metrics = []
    all_importances = []

    # 带进度条的实验循环
    for _ in tqdm(range(N_REPEATS), desc="实验进度", unit="run"):
        metrics, importances = do_once()
        all_metrics.append(metrics)
        all_importances.append(importances)

    # 结果处理（增加版本保存）
    results_df = pd.DataFrame(np.array(all_metrics), columns=['R²', 'CCC', 'RMSE', 'MAE'])
    timestamp = datetime.now().strftime("%Y%m%d_%H%M")
    results_df.to_excel(f'rf_results_{timestamp}.xlsx', index=False)

    # 特征重要性分析（保持原名）
    data = pd.read_excel(r'C:\Users\32407\Desktop\soil-terrain attributes.xlsx')
    feature_names = data.drop('SD', axis=1).columns
    mean_importances = np.mean(all_importances, axis=0)

    # 可视化（改用增强版）
    sorted_idx = np.argsort(mean_importances)[::-1]
    plot_importance(feature_names[sorted_idx], mean_importances[sorted_idx])

    print(f"\n总实验时间: {time.time() - start_experiment:.2f}秒")
